﻿using namespace std;
#include<iostream>
#include<functional>

//int main()
//{
//	// 两个数相加的lambda
//	auto add1 = [](int a, int b)->int{return a + b; };
//	cout << add1(1, 2) << endl;
//
//	// 省略返回值
//	auto add2 = [](int a, int b){return a + b; };
//	cout << add2(1, 2) << endl;
//
//	// 交换变量的lambda
//	int x = 0, y = 1;
//	auto swap1 = [](int& x1, int& x2)->void{int tmp = x1; x1 = x2; x2 = tmp; };
//	swap1(x, y);
//	cout << x << ":" << y << endl;
//
//	auto swap2 = [](int& x1, int& x2)
//	{
//		int tmp = x1;
//		x1 = x2;
//		x2 = tmp;
//	};
//
//	swap2(x, y);
//	cout << x << ":" << y << endl;
//
//	// 不传参数交换x y的lambda  -- 捕捉列表
//	// 默认捕捉的对象不能修改
//	/*auto swap3 = [x, y]()mutable
//	{
//		int tmp = x;
//		x = y;
//		y = tmp;
//	};
//
//	swap3();
//	cout << x << ":" << y << endl;*/
//
//	auto swap3 = [&x, &y]
//	{
//		int tmp = x;
//		x = y;
//		y = tmp;
//	};
//
//	swap3();
//	cout << x << ":" << y << endl;
//
//	system("pause");
//	return 0;
//}




// 1、生命周期（存储区域）
// 2、作用域（编译器编译，用的地方能否找到）
//static int f = 1;
//
//int func()
//{
//	int a, b, c, d, e;
//	a = b = c = d = e = 1;
//
//	// 全部传值捕捉
//	auto f1 = [=](){
//		cout << a << b << c << d << e << endl;
//	};
//
//	f1();
//
//	// 混合捕捉
//	auto f2 = [=, &a](){
//		a++;
//		cout << a << b << c << d << e << endl;
//	};
//
//	f2();
//	cout << a << b << c << d << e << endl;
//	
//	static int x = 0;
//
//	if (a)
//	{
//		auto f3 = [&, a](){
//			//a++;
//			b++;
//			c++;
//			d++;
//			e++;
//			f++;
//			x++;
//			cout << a << b << c << d << e << endl;
//		};
//		f3();
//	}
//	system("pause");
//	return 0;
//}
//
//
//int main()
//{
//	func();
//	return 0;
//}



//int main()
//{
//	// 最简单的lambda表达式, 该lambda表达式没有任何意义
//	[] {};
//
//	// 省略参数列表和返回值类型，返回值类型由编译器推导为int
//	int a = 3, b = 4;
//	[=] {return a + 3; };
//
//	// 省略了返回值类型，无返回值类型
//	auto fun1 = [&](int c) {b = a + c; };
//	fun1(10);
//	cout << a << " " << b << endl;
//
//	// 各部分都很完善的lambda函数
//	auto fun2 = [=, &b](int c)->int {return b += a + c; };
//	cout << fun2(10) << endl;
//
//	// 复制捕捉x
//	int x = 10;
//	auto add_x = [x](int a) mutable { x *= 2; return a + x; };
//	cout << add_x(10) << endl;
//
//	system("pause");
//	return 0;
//}



//void (*PF)();
//int main()
//{
//	auto f1 = [] {cout << "hello world" << endl; };
//	auto f2 = [] {cout << "hello world" << endl; };
//	// 此处先不解释原因，等lambda表达式底层实现原理看完后，大家就清楚了
//	//f1 = f2;   // 编译失败--->提示找不到operator=()
//	
//	// 允许使用一个lambda表达式拷贝构造一个新的副本
//	auto f3(f2);
//	f3();
//	
//	// 可以将lambda表达式赋值给相同类型的函数指针
//	PF = f2;
//	PF();
//
//	system("pause");
//	return 0;
//}




//class Rate
//{
//public:
//	Rate(double rate) : _rate(rate)
//	{}
//
//	double operator()(double money, int year)
//	{
//		return money * _rate * year;
//	}
//
//private:
//	double _rate;
//};
//
//
//int main()
//{
//	// 函数对象
//	double rate = 0.49;
//	Rate r1(rate);
//	r1(10000, 2);
//
//	// 仿函数lambda_uuid
//	// lambda -> lambda_uuid
//	auto r2 = [=](double monty, int year)->double{return monty*rate*year; };
//	r2(10000, 2);
//
//	auto r3 = [=](double monty, int year)->double{return monty*rate*year; };
//	r3(10000, 2);
//
//	return 0;
//}



//template<class F, class T>
//T useF(F f, T x)
//{
//	static int count = 0;
//	cout << "count:" << ++count << endl;
//	cout << "count:" << &count << endl;
//
//	return f(x);
//}
//
//
//double f(double i)
//{
//	return i / 2;
//}
//
//struct Functor
//{
//	double operator()(double d)
//	{
//		return d / 3;
//	}
//};
//
//int main()
//{
//	// 函数指针
//	cout << useF(f, 11.11) << endl;
//
//	// 函数对象
//	cout << useF(Functor(), 11.11) << endl;
//
//	// lamber表达式对象
//	cout << useF([](double d)->double{ return d / 4; }, 11.11) << endl;
//
//	// 快捷键--对应行为
//	// 事件响应
//	//map<string, >
//
//	system("pause");
//	return 0;
//}



//int f(int a, int b)
//{
//	return a + b;
//}
//
//struct Functor
//{
//public:
//	int operator() (int a, int b)
//	{
//		return a + b;
//	}
//};
//
//class Plus
//{
//public:
//	static int plusi(int a, int b)
//	{
//		return a + b;
//	}
//
//	double plusd(double a, double b)
//	{
//		return a + b;
//	}
//};
//
//int main()
//{
//	function<int(int, int)> f1 = f;
//	f1(1, 2);
//
//	function<int(int, int)> f2 = Functor();
//	f2(1, 2);
//
//	function<int(int, int)> f3 = Plus::plusi;
//	f3(1, 2);
//
//	function<double(Plus, double, double)> f4 = &Plus::plusd;
//	f4(Plus(), 1.1, 2.2);
//
//	return 0;
//}



//template<class F, class T>
//T useF(F f, T x)
//{
//	static int count = 0;
//	cout << "count:" << ++count << endl;
//	cout << "count:" << &count << endl;
//
//	return f(x);
//}
//
//double f(double i)
//{
//	return i / 2;
//}
//
//struct Functor
//{
//	double operator()(double d)
//	{
//		return d / 3;
//	}
//};
//
//int main()
//{
//
//	//调用了同一份useF
//	
//	// 函数指针
//	function<double(double)> f1 = f;
//	cout << useF(f1, 11.11) << endl;
//
//	// 函数对象
//	function<double(double)> f2 = Functor();
//	cout << useF(f2, 11.11) << endl;
//
//	// lamber表达式对象
//	function<double(double)> f3 = [](double d)->double{ return d / 4; };
//	cout << useF(f3, 11.11) << endl;
//	system("pause");
//	return 0;
//}


using namespace placeholders;
#include<map>
#include<vector>
#include<stack>
//力扣::150. 逆波兰表达式求值s
//class Solution {
//public:
//    int evalRPN(vector<string>& tokens) {
//        stack<int> st;
//        map<string, function<long long(long long x, long long y)>> openfunmap =
//        {
//            {"+",[](long long x,long long y) {return x + y; }},
//            {"-",[](long long x,long long y) {return x - y; }},
//            {"*",[](long long x,long long y) {return x * y; }},
//            {"/",[](long long x,long long y) {return x / y; }},
//        };
//
//        for (auto& x : tokens)
//        {
//            if (openfunmap.count(x))
//            {
//                long long right = st.top();
//                st.pop();
//                long long left = st.top();
//                st.pop();
//                st.push(openfunmap[x](left, right));
//            }
//            else
//            {
//                st.push(stoll(x));
//            }
//        }
//
//        return st.top();
//    }
//};



//
//int Div(int a, int b)
//{
//	return a / b;
//}
//
//int Plus(int a, int b)
//{
//	return a + b;
//}
//
//double Mul(int a, int b, double rate)
//{
//	return a * b * rate;
//}
//
//class Sub
//{
//public:
//	int sub(int a, int b)
//	{
//		return a - b;
//	}
//};
//// 11:50继续
//int main()
//{
	// 调整个数, 绑定死固定参数
	function<int(int, int)> funcPlus = Plus;
	//function<int(Sub, int, int)> funcSub = &Sub::sub;
	function<int(int, int)> funcSub = bind(&Sub::sub, Sub(), _1, _2);
	function<int(int, int)> funcMul = bind(Mul, _1, _2, 1.5);
	map<string, function<int(int, int)>> opFuncMap =
	{
		{ "+", Plus},
		{ "-", bind(&Sub::sub, Sub(), _1, _2)}
	};
//
//	cout << funcPlus(1, 2) << endl;
//	cout << funcSub(1, 2) << endl;
//	cout << funcMul(2, 2) << endl;
//
//	cout << opFuncMap["+"](1, 2) << endl;
//	cout << opFuncMap["-"](1, 2) << endl;
//
//
//
//	int x = 2, y = 10;
//	cout << Div(x, y) << endl;
//
//	// 调整顺序 -- 鸡肋
//	// _1 _2.... 定义在placeholders命名空间中，代表绑定函数对象的形参，
//	// _1，_2...分别代表第一个形参、第二个形参...
//	//bind(Div, placeholders::_1, placeholders::_2);
//	auto bindFunc1 = bind(Div, _1, _2);
//	function<int(int, int)> bindFunc2 = bind(Div, _2, _1);
//	cout << bindFunc1(x, y) << endl;
//	cout << bindFunc2(x, y) << endl;
//
//
//	system("pause");
//	return 0;
//}


// 使用举例
#include <functional>
int Plus(int a, int b)
{
	return a + b;
}
class Sub
{
public:
	int sub(int a, int b)
	{
		return a - b;
	}
};
int main()
{
	//表示绑定函数plus 参数分别由调用 func1 的第一，二个参数指定
	std::function<int(int, int)> func1 = std::bind(Plus, placeholders::_1,
		placeholders::_2);
	//auto func1 = std::bind(Plus, placeholders::_1, placeholders::_2);
	// 
	// 
	//func2的类型为 function<void(int, int, int)> 与func1类型一样
	//表示绑定函数 plus 的第一，二为： 1， 2
	auto func2 = std::bind(Plus, 4,3);
	cout << func1(1, 2) << endl;
	cout << func2() << endl;
	Sub s;


	// 绑定成员函数
	std::function<int(int, int)> func3 = std::bind(&Sub::sub, s,placeholders::_1, placeholders::_2);
	
	// 参数调换顺序
	std::function<int(int, int)> func4 = std::bind(&Sub::sub, s,placeholders::_2, placeholders::_1);
	cout << func3(1, 2) << endl;
	cout << func4(1, 2) << endl;
	return 0;
}